package assignment5;
///#####################################################################################///
///*************************************************************************************///
///Created by David Schwartz(Student#: 301047179) and Michael Quong(Student#: 301041935)///
///*************************************************************************************///
///#####################################################################################///

import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class MainNoThanks {

	String fscore = "";
	String pcards = "";
	private static JTextArea status;
	public static JTextArea scores;
	Integer numPlayersx;
	public static JTextArea your;
	
	public static void main(String[] args) {
		JFrame frame = new JFrame("No Thanks");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JPanel primary = new JPanel();
		primary.setLayout(new BorderLayout());
		primary.setBackground(new Color(5,90,30));
		status = new JTextArea(2, 20);
		status.setBackground(new Color(28, 170, 30));
		status.setEditable(false);
		status.setFont(new Font("Serif", Font.BOLD, 16));
		primary.add(status, BorderLayout.NORTH);
		
		scores = new JTextArea(7, 30);
		scores.setBackground(new Color(35, 214, 38));
		scores.setEditable(false);
		scores.setFont(new Font("Serif", Font.BOLD, 16));
		primary.add(scores, BorderLayout.CENTER);
		
		your = new JTextArea(5, 30);
		your.setBackground(new Color(42, 255, 46));
		your.setEditable(false);
		your.setFont(new Font("Serif", Font.BOLD, 16));
		primary.add(your, BorderLayout.SOUTH);
		
		frame.getContentPane().add(primary);
		frame.pack();
		frame.setSize(800, 600);
		frame.setResizable(true);
		frame.setLocation((frame.getHeight() / 2), (frame.getWidth() / 3));
		frame.setVisible(true);
		MainNoThanks game = new MainNoThanks();
		game.mainLoop();
	}
	
	public void mainLoop() {
		// main loop
		boolean playAgain = true;
		while (playAgain) {
			int n = getNumPlayersFromUser();
			if (n > 0) {
				ArrayList<Player> players = makePlayers(n);
				Pot pot = new Pot(players);

				int p = 0;
				while (pot.cardsLeft()) {
					Move move = playOneRound(pot, players.get(p));
					if (move.equals(Move.noThanks)) {
						p = (p + 1) % players.size();
					}
				}
				displayFinalScores(players);
			}
			playAgain = askToPlayAgain();
		}
		JOptionPane.showMessageDialog(null, "Bye bye! Thanks for playing.", "Bye!", JOptionPane.ERROR_MESSAGE);
	}

	public int getNumPlayersFromUser() {
		 Object[] possibleValues = {2,3,4};
		 Integer selectedValue = (Integer) JOptionPane.showInputDialog(null,
		            "How Many Players?", "Players",
		            JOptionPane.QUESTION_MESSAGE, null,
		            possibleValues, possibleValues[0]);
		 numPlayersx = selectedValue;
		 if (selectedValue == null) {
			 return 0;
		 } else {
			 return selectedValue;			 
		 } 
	}
	

	// add 1 human player and n-1 computer players
	public ArrayList<Player> makePlayers(int n) {
		ArrayList<Player> result = new ArrayList<Player>();
		result.add(new HumanPlayer());
		for (int i = 1; i < n; ++i) {
			result.add(ComputerPlayer.randomComputerPlayer());
			// result.add(new RandomPlayer("Randy" + i));
		}

		// randomly chosen players goes first
		Collections.shuffle(result);

		return result;
	}

	public Move playOneRound(Pot pot, Player p) {
		Move move = p.makeAmove(pot);
		if (move.equals(Move.noThanks)) {
			// the player doesn't want the card, so they add a chip
			status.setText(p.getName() + " added a chip to the pot");
			p.removeOneChip();
			pot.addOneChip();
		} else {
			// the player has taken the card!
			status.setText(p.getName() + " has took the " + pot.getUpCard() + " and " +
					pot.getNumChips() + " chips (" + pot.getNumCards() + " cards remain)");
			p.addChips(pot.getNumChips());
			p.addCard(pot.getUpCard());
			pot.clearChips();
			if (pot.cardsLeft()) {
				pot.nextCard();
			}
		}
		return move;
	}

	// doesn't check for ties!
	public void displayFinalScores(ArrayList<Player> players) {
		IntArray scores = new IntArray();
		for (Player p : players) {
			scores.add(p.calculateScore());
		}
		int mi = scores.indexOfMax();
		JOptionPane.showMessageDialog(null, "!!! The winner is: " +
				players.get(mi).getName() + "! Score: " + scores.get(mi) + "!!!", "Winner", JOptionPane.ERROR_MESSAGE);

		// display final scores
		for (Player p : players) {
			fscore += " " + p.getName() + " " + p.calculateScore() + " " + p.getNumChips() + " " + p.getCards() + " \n";
		}
		JOptionPane.showMessageDialog(null, fscore, "Final Scores", JOptionPane.ERROR_MESSAGE);
	}

	public boolean askToPlayAgain() {
		 Object[] possibleValues = {"Yes", "No"};
		 String selectedValue = (String) JOptionPane.showInputDialog(null,
		            "Would you like to play again?", "Play again",
		            JOptionPane.QUESTION_MESSAGE, null,
		            possibleValues, possibleValues[0]);
		 if (selectedValue == "Yes") {
			 return true;
		 } else {
			 return false;
		 }
	}

	// Pot is private inner class so that Player objects cannot cast
	// PlayerPot to get at other player's chips, or the unviewed cards
	private class Pot implements PlayerPot {
		private int numChips;

		private IntArray deck;

		private List<IntArray> playerCards;

		private List<String> playerNames;

		public Pot(ArrayList<Player> players) {
			this.numChips = 0;
			makeDeck();
			playerCards = new List<IntArray>();
			playerNames = new List<String>();
			for (Player p : players) {
				playerCards.add(p.getCards());
				playerNames.add(p.getName());
			}
		}

		// return a copy of the cards all players currently hold
		public List<IntArray> getPlayerCards() {
			return playerCards.copy();
		}

		// return a copy of the names of all the player
		public List<String> getPlayerNames() {
			return playerNames.copy();
		}

		public void printPlayerCards() {
			pcards = "";
			for (int i = 0; i < playerCards.size(); ++i) {
				pcards += playerNames.get(i) + " cards: " + playerCards.get(i) + "\n";
			}
			scores.setText(pcards);
		}

		public int getNumChips() {
			return numChips;
		}

		public int getNumCards() {
			return deck.size();
		}

		public void clearChips() {
			numChips = 0;
		}

		public void addOneChip() {
			++numChips;
		}

		public int getUpCard() {
			return deck.first();
		}

		public boolean cardsLeft() {
			return deck.size() > 0;
		}

		public void nextCard() {
			deck.remove(0);
		}

		private void makeDeck() {
			deck = new IntArray();

			// initialize the deck: cards go from 3 to 35
			for (int i = 3; i <= 35; ++i) {
				deck.add(i);
			}

			// mix up the cards
			deck.shuffle();

			// remove 9 cards
			for (int i = 0; i < 9; ++i) {
				deck.remove(deck.size() - 1);
			}
		}

	}

}
